package org.liverpool.trial;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.util.ArrayList;

public class RandomIndexFile {

	public class ProteinNameAndByteLocation{
		public String protAccn;
		public long startByte;
		public long endByte;
		
		public ProteinNameAndByteLocation(String prot, long start, long end){
			protAccn = prot;
			startByte = start;
			endByte = end;
		}
	};

	ArrayList<ProteinNameAndByteLocation> proteinRecords = new ArrayList<ProteinNameAndByteLocation>();
		

	/**
	 * Read the ProteinNameAndByteLocation ArrayList and use the byte indices to
	 * retrieve the location of protein records
	 * 
	 * @inputFile - The Summary file
	 * @outputFile - The file where the bytes read from the Summary file will be written 
	 * @throws Exception
	 */
	public void retrieveDataFromFileByreadingIndex(String inputFile,String outFile) throws Exception{
		
		FileOutputStream fout = new FileOutputStream(new File(outFile));
		BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new DataOutputStream(fout)));
		
		RandomAccessFile randomFile = new RandomAccessFile(new File(inputFile),"r");
		
		// Read the ArrayList<ProteinNameAndByteLocation> element by element and
		// get ProteinAccn + start byte index + end byte index....use these byte 
		//locations to access the file in random manner.
		
		//System.out.println("\n Entering the retrieveDataFromFileByreadingIndex()");
		
		for(int i =0 ;i < proteinRecords.size(); i++){
			
			ProteinNameAndByteLocation p = proteinRecords.get(i) ;
			
			String protName = p.protAccn;
			long start = p.startByte;
			long end = p.endByte;
			
			randomFile.seek(start);
			int buffLength = (int)(end - start);
			
			byte [] buffer = new byte[buffLength];
			
			int totalRead = randomFile.read(buffer, 0, buffLength);
			
			String content = new String(buffer);
			content = content.trim();
			
			//System.out.println("\n" + protName + " start = " + start + " end = " + end + "\n" + content);
			
			out.write("\n" + protName + " start = " + start + " end = " + end + "\n" + content);
			out.write("\n ***************************** ");
		}
		
		randomFile.close();
		out.close();
		
	}
	
	/**
	 * 
	 * @param inputFile
	 * @throws Exception
	 */
	public void retrieveDataByRandomAccessFile(String inputFile) throws Exception{
				
		RandomAccessFile randomFile = new RandomAccessFile(new File(inputFile),"r");
				
		String strLine = "";
		String protAccn = "";
		String prevProtAccn = "";
		long endPosition = 0;
		
		long startPosition = randomFile.getFilePointer();
		
		while((strLine = randomFile.readLine()) != null){
		
			String [] records = strLine.split("\t");	
			
			if(records.length == 0)
				continue;
			
			protAccn = records[0].trim();
			
			if(protAccn.length() > 1){
				prevProtAccn = protAccn;
				String newLine = "";
				String strLine_2 = "";
				long fileMarker = -1;
			
				do{
					fileMarker = randomFile.getFilePointer(); // Mark the location before reading another line	
					if((strLine_2 = randomFile.readLine()) != null){
						if(strLine_2.contains("\t")){
							String [] records_next = strLine_2.split("\t");
							newLine = records_next[0].trim();
							System.out.println(" In the loop : " + newLine);
						}
					}else{
						newLine = "Hip-Hop !! Go out !!";
					}
				}while(newLine.length() < 1);
							
				// Reset the see location to beginning of the last line read
				if(fileMarker != -1)
					randomFile.seek(fileMarker);
				
				endPosition = randomFile.getFilePointer() - 1;
				
				ProteinNameAndByteLocation p = new ProteinNameAndByteLocation(prevProtAccn, startPosition, endPosition);
        		proteinRecords.add(p);
        		
        		startPosition = endPosition + 1;
			}
			
		}
		
		randomFile.close();
		
	}
	
	
	/**
	 * 
	 * @param args
	 * @throws Exception
	 */
	public static void main(String [] args) throws Exception {
		
		try{
			RandomIndexFile rif = new RandomIndexFile();
			//rif.makeIndex (args[0]);
			rif.retrieveDataByRandomAccessFile(args[0]);
			rif.retrieveDataFromFileByreadingIndex(args[0],args[1]);
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	

}
